unit DataObject;

interface

uses
  Constant, DI;

type
  TSourceData = class(TObject)
  protected
    FCount: Integer;
    function CheckValidIndex(const Index: Integer): Boolean;
    function GetTime(const Index: Integer): TimeType; virtual;
    function GetHigh(const Index: Integer): ValueType; virtual;
    function GetLow(const Index: Integer): ValueType; virtual;
  public
    property Time[const Index: Integer]: TimeType read GetTime;
    property High[const Index: Integer]: ValueType read GetHigh;
    property Low[const Index: Integer]: ValueType read GetLow;
    property Count: Integer read FCount;
  end;

  TBarSourceData = class(TSourceData)
  private
    FPHighBuf: PDataBuf;
    FPLowBuf: PDataBuf;
    FPDateBuf: PDataBuf;
    FPTimeBuf: PDataBuf;
  protected
    function GetTime(const Index: Integer): TimeType; override;
    function GetHigh(const Index: Integer): ValueType; override;
    function GetLow(const Index: Integer): ValueType; override;
  public
    constructor Create(AHighBuf, ALowBuf, ADateBuf, ATimeBuf: PDataBuf;
      ACount: Integer);
  end;

  TSeriesSourceData = class(TSourceData)
  private
    FPStkDataBuf: PStkDataBuf;
  protected
    function GetTime(const Index: Integer): TimeType; override;
    function GetHigh(const Index: Integer): ValueType; override;
    function GetLow(const Index: Integer): ValueType; override;
  public
    constructor Create(ASourceData: PStkDataBuf; ACount: Integer);
  end;

implementation

uses
  Math, DateUtils, SysUtils;

{ TSourceData }

function TSourceData.CheckValidIndex(const Index: Integer): Boolean;
begin
  Result := (Index > INVALIDPOS) or (Index < FCount);
end;

function TSourceData.GetHigh(const Index: Integer): ValueType;
begin
  Result := InValidValue;
end;

function TSourceData.GetLow(const Index: Integer): ValueType;
begin
  Result := InValidValue;
end;

function TSourceData.GetTime(const Index: Integer): TimeType;
begin
  Result := ZeroValue;
end;

{ TSeriesSourceData }

constructor TSeriesSourceData.Create(ASourceData: PStkDataBuf; ACount: Integer);
begin
  FPStkDataBuf := ASourceData;
  FCount       := ACount;
end;

function TSeriesSourceData.GetHigh(const Index: Integer): ValueType;
begin
  if CheckValidIndex(Index) then
    Result := FPStkDataBuf^[Index].high
  else
    Result := inherited GetHigh(Index);
end;

function TSeriesSourceData.GetLow(const Index: Integer): ValueType;
begin
  if CheckValidIndex(Index) then
    Result := FPStkDataBuf^[Index].low
  else
    Result := inherited GetLow(Index);
end;

function TSeriesSourceData.GetTime(const Index: Integer): TimeType;
begin
  if CheckValidIndex(Index) then
    Result := FPStkDataBuf^[Index].time
  else
    Result := inherited GetTime(Index);
end;

{ TBarSourceData }

constructor TBarSourceData.Create(AHighBuf, ALowBuf,ADateBuf, ATimeBuf: PDataBuf;
  ACount: Integer);
begin
  FPHighBuf := AHighBuf;
  FPLowBuf  := ALowBuf;
  FPTimeBuf := ATimeBuf;
  FPDateBuf := ADateBuf;
  FCount    := ACount;
end;

function TBarSourceData.GetHigh(const Index: Integer): ValueType;
begin
  if CheckValidIndex(Index) then
    Result := FPHighBuf^[Index]
  else
    Result := inherited GetHigh(Index);
end;

function TBarSourceData.GetLow(const Index: Integer): ValueType;
begin
  if CheckValidIndex(Index) then
    Result := FPLowBuf^[Index]
  else
    Result := inherited GetLow(index);
end;

function TBarSourceData.GetTime(const Index: Integer): TimeType;
begin
  if CheckValidIndex(Index) then
    Result := Trunc(FPTimeBuf^[Index])
  else
    Result := inherited GetTime(Index);
end;

end.
